In [2]:
from PIL import Image
image = Image.open("../W4/3steps.png")
image
Out[2]:
In [1]:
from fastai import * 
from fastai.text import *
import pandas as pd 
import numpy as np
import warnings 
warnings.filterwarnings('ignore')
In [124]:
#import torch
#defaults.device = torch.device('cpu')

# this is to resolve issue of 'RuntimeError: DataLoader worker is killed by signal' when running learn_clas.lr_find()

Load the data, prepare the language model

What is a language model? It has a very specific meaning. A language model is something which predicts next word in a sentence. To predict next word in a sentence you need to know quite a lot about the English language.

https://forums.fast.ai/t/deep-learning-lesson-4-notes/30983

Why is that useful? Because at that point we have got a model that knows how to complete sentences like this. So it knows quite a lot about English and a lot about how the world works. What kinds of things tend to be hot in different situations, for instance. Ideally, it would learn things like in 1996 in a speech to the United Nations, United States President __ said… That will be a really good language model because it needs to know who was the president in that year. Getting really good at training language model is a great way to learn or teach a neural net a lot about what is our world, what’s in our world or how do things work in our world. It’s really a fascinating topic.

In [11]:
dataset = pd.read_csv('../W4/trial.csv', sep = ',')
In [12]:
df = dataset[['overall', 'reviewText']]
In [13]:
df.head()
Out[13]:
overall reviewText
0 1 This is NOT what you get. This case has a stic...
1 1 Headline says 30000 mah\nDiscription reads 800...
2 1 Fit the phone nicely, but the first time I dro...
3 1 I ordered 2 of these. I bent the clip on mine...
4 1 Cheap material
In [14]:
df = df.replace({'overall': {1: 'Neg', 2: 'Neg', 4: 'Pos', 5: 'Pos'}})
In [15]:
df2 = df[df['overall']!=3]
In [16]:
len(df2)
Out[16]:
11558

Take unlabelled dataset, use it to fine-tune the pretrained model built with wikitext-103 dataset

Process the unlabelled dataset using TextDataBunch()

In [2]:
path = ''
np.random.seed(42)
bs=48
In [18]:
data_lm = (TextList.from_df(df2, cols ='reviewText')
          .split_by_rand_pct(0.2)
          .label_for_lm()
          .databunch(bs=bs))
In [19]:
data_lm.save('data_lm_export_no3.pkl')
In [20]:
data_lm.show_batch()
idx text
0 steel , xxunk xxunk apple watch is and turned into a what can only be described as a low cost entry level plastic watch . i think i had higher expectations for the product then i received as the image clearly shows a green metallic xxunk to the case that was not the finish i received xxbos xxmaj it is garbage do n't waste your money mine worked for a
1 this is not a brand name and is a knock off xxbos i purchase this xxunk because it was unlocked but it was false just connected request the unlock code the second time it was connected even it was xxunk by the pc xxbos xxmaj for the most part is what it says . xxmaj mine arrived put them on and noticed one is chipped on the side so i
2 memory just sitting xxunk . xxup xxunk is useless as the phone does nt have the power to utilize it . \n i honestly ca nt wait to xxunk this phone into dust . xxbos xxmaj cheap looking xxbos xxmaj will not fit xxmaj samsung xxmaj galaxy xxmaj note 3 w / xxmaj otterbox xxmaj defender series case protector . \n xxmaj will not fit even without any
3 but all 3 were way off on the cutting . xxmaj to line up the ear hole , it causes the button hole to be misaligned and on top of that the whole thing was too large . it caused bubbles around the whole xxunk because it would not fit inside of the xxunk which is slightly higher than the screen . xxmaj horrible xxup qc to say the least
4 phone was the answer . xxbos xxmaj what a xxunk of garbage . xxunk my xxunk but i am not happy about spending xxunk dollars for this useless xxunk for a lens . i used xxmaj iphone 6plus only very middle of image is sharp if that , rest of the image is a total blurry haze . xxbos i purchased an anker xxunk and it stated that this was

Run the above code once, load the data_lm whenever needed

We can then put this in a learner object very easily with a model loaded with the pretrained weights. They'll be downloaded the first time you'll execute the following line and stored in ~/.fastai/models (or a specified path)

In [3]:
data_lm = load_data(path, 'data_lm_export_no3.pkl')
In [4]:
learn = language_model_learner(data_lm, arch=AWD_LSTM, pretrained=True, drop_mult=0.3)
In [23]:
learn.lr_find()
50.00% [1/2 04:31<04:31]
epoch train_loss valid_loss accuracy time
0 5.222558 #na# 04:31

45.59% [31/68 02:20<02:47 9.6657]
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [24]:
learn.recorder.plot(suggestion = True)
Min numerical gradient: 3.98E-02
Min loss divided by 10: 4.37E-02
In [25]:
# max_lr will be the 10th of the mininum of the curve = min lss divided by 10: 3.63E-02
learn.fit_one_cycle(1, 4.37e-2, moms=(0.8, 0.7))
epoch train_loss valid_loss accuracy time
0 3.952430 3.628223 0.277579 04:53
In [26]:
learn.save('fit_head_no3')
In [27]:
learn.load('fit_head_no3')
Out[27]:
LanguageLearner(data=TextLMDataBunch;

Train: LabelList (9247 items)
x: LMTextList
xxbos xxmaj xxunk says 3 xxrep 4 0 mah 
  xxmaj xxunk reads xxunk mah 
  xxmaj features reads xxunk mah 
  xxmaj makes you wonder xxunk,xxbos xxmaj fit the phone nicely , but the first time i dropped it the glass shattered .,xxbos xxmaj cheap material,xxbos xxmaj unfortunately i felt that this cover or sleeve took a beautiful piece of art , which the xxunk stainless steel , xxunk xxunk apple watch is and turned into a what can only be described as a low cost entry level plastic watch . i think i had higher expectations for the product then i received as the image clearly shows a green metallic xxunk to the case that was not the finish i received,xxbos xxmaj it is garbage do n't waste your money mine worked for a month then it gave me problems not connecting and just being a hassle ... xxmaj this is not xxunk xxunk why ca n't the just make a simple wire ? ? ?
y: LMLabelList
,,,,
Path: .;

Valid: LabelList (2311 items)
x: LMTextList
xxbos i bought this for a xxunk xxunk . i have one just like it that was bought earlier in the year and it is great . xxmaj this is a great price for a nice , good cover . xxmaj the color is a deep gorgeous color .,xxbos xxmaj case broke on the first drop .,xxbos xxmaj works xxmaj great !,xxbos xxmaj the phone is xxunk , the information about the device tells xxmaj nokia xxunk instead of xxmaj nokia xxunk . xxmaj the phone did n't come with the original box and xxunk . xxmaj all this information should be indicated in xxunk . xxmaj really bad , because is a xxunk . xxmaj at least the xxmaj price should be less that the current .,xxbos xxmaj junk !
y: LMLabelList
,,,,
Path: .;

Test: None, model=SequentialRNN(
  (0): AWD_LSTM(
    (encoder): Embedding(3464, 400, padding_idx=1)
    (encoder_dp): EmbeddingDropout(
      (emb): Embedding(3464, 400, padding_idx=1)
    )
    (rnns): ModuleList(
      (0): WeightDropout(
        (module): LSTM(400, 1152, batch_first=True)
      )
      (1): WeightDropout(
        (module): LSTM(1152, 1152, batch_first=True)
      )
      (2): WeightDropout(
        (module): LSTM(1152, 400, batch_first=True)
      )
    )
    (input_dp): RNNDropout()
    (hidden_dps): ModuleList(
      (0): RNNDropout()
      (1): RNNDropout()
      (2): RNNDropout()
    )
  )
  (1): LinearDecoder(
    (decoder): Linear(in_features=400, out_features=3464, bias=True)
    (output_dp): RNNDropout()
  )
), opt_func=functools.partial(<class 'torch.optim.adam.Adam'>, betas=(0.9, 0.99)), loss_func=FlattenedLoss of CrossEntropyLoss(), metrics=[<function accuracy at 0x1a1f22d200>], true_wd=True, bn_wd=True, wd=0.01, train_bn=True, path=PosixPath('.'), model_dir='models', callback_fns=[functools.partial(<class 'fastai.basic_train.Recorder'>, add_time=True, silent=False)], callbacks=[RNNTrainer
learn: ...
alpha: 2.0
beta: 1.0], layer_groups=[Sequential(
  (0): WeightDropout(
    (module): LSTM(400, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 400, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): Embedding(3464, 400, padding_idx=1)
  (1): EmbeddingDropout(
    (emb): Embedding(3464, 400, padding_idx=1)
  )
  (2): LinearDecoder(
    (decoder): Linear(in_features=400, out_features=3464, bias=True)
    (output_dp): RNNDropout()
  )
)], add_time=True, silent=False)

To complete the fine-tuning, we can then unfreeze and launch a new training

In [29]:
learn.unfreeze()
learn.fit_one_cycle(10, 4.37e-3, moms=(0.8, 0.7))
epoch train_loss valid_loss accuracy time
0 3.382586 3.511436 0.293204 07:42
1 3.284490 3.478412 0.294482 32:16
2 3.138240 3.489088 0.296317 07:21
3 2.831772 3.561687 0.293936 07:32
4 2.432294 3.725453 0.283594 07:53
5 1.952469 3.946027 0.278063 07:45
6 1.503035 4.169585 0.271243 34:07
7 1.149710 4.317840 0.268018 07:26
8 0.902408 4.400008 0.265997 29:40
9 0.788415 4.415461 0.265253 07:36
In [30]:
learn.save('fine_tuned_no3')
In [5]:
learn.load('fine_tuned_no3')
Out[5]:
LanguageLearner(data=TextLMDataBunch;

Train: LabelList (9247 items)
x: LMTextList
xxbos xxmaj xxunk says 3 xxrep 4 0 mah 
  xxmaj xxunk reads xxunk mah 
  xxmaj features reads xxunk mah 
  xxmaj makes you wonder xxunk,xxbos xxmaj fit the phone nicely , but the first time i dropped it the glass shattered .,xxbos xxmaj cheap material,xxbos xxmaj unfortunately i felt that this cover or sleeve took a beautiful piece of art , which the xxunk stainless steel , xxunk xxunk apple watch is and turned into a what can only be described as a low cost entry level plastic watch . i think i had higher expectations for the product then i received as the image clearly shows a green metallic xxunk to the case that was not the finish i received,xxbos xxmaj it is garbage do n't waste your money mine worked for a month then it gave me problems not connecting and just being a hassle ... xxmaj this is not xxunk xxunk why ca n't the just make a simple wire ? ? ?
y: LMLabelList
,,,,
Path: .;

Valid: LabelList (2311 items)
x: LMTextList
xxbos i bought this for a xxunk xxunk . i have one just like it that was bought earlier in the year and it is great . xxmaj this is a great price for a nice , good cover . xxmaj the color is a deep gorgeous color .,xxbos xxmaj case broke on the first drop .,xxbos xxmaj works xxmaj great !,xxbos xxmaj the phone is xxunk , the information about the device tells xxmaj nokia xxunk instead of xxmaj nokia xxunk . xxmaj the phone did n't come with the original box and xxunk . xxmaj all this information should be indicated in xxunk . xxmaj really bad , because is a xxunk . xxmaj at least the xxmaj price should be less that the current .,xxbos xxmaj junk !
y: LMLabelList
,,,,
Path: .;

Test: None, model=SequentialRNN(
  (0): AWD_LSTM(
    (encoder): Embedding(3464, 400, padding_idx=1)
    (encoder_dp): EmbeddingDropout(
      (emb): Embedding(3464, 400, padding_idx=1)
    )
    (rnns): ModuleList(
      (0): WeightDropout(
        (module): LSTM(400, 1152, batch_first=True)
      )
      (1): WeightDropout(
        (module): LSTM(1152, 1152, batch_first=True)
      )
      (2): WeightDropout(
        (module): LSTM(1152, 400, batch_first=True)
      )
    )
    (input_dp): RNNDropout()
    (hidden_dps): ModuleList(
      (0): RNNDropout()
      (1): RNNDropout()
      (2): RNNDropout()
    )
  )
  (1): LinearDecoder(
    (decoder): Linear(in_features=400, out_features=3464, bias=True)
    (output_dp): RNNDropout()
  )
), opt_func=functools.partial(<class 'torch.optim.adam.Adam'>, betas=(0.9, 0.99)), loss_func=FlattenedLoss of CrossEntropyLoss(), metrics=[<function accuracy at 0x1a26ed4290>], true_wd=True, bn_wd=True, wd=0.01, train_bn=True, path=PosixPath('.'), model_dir='models', callback_fns=[functools.partial(<class 'fastai.basic_train.Recorder'>, add_time=True, silent=False)], callbacks=[RNNTrainer
learn: ...
alpha: 2.0
beta: 1.0], layer_groups=[Sequential(
  (0): WeightDropout(
    (module): LSTM(400, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 400, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): Embedding(3464, 400, padding_idx=1)
  (1): EmbeddingDropout(
    (emb): Embedding(3464, 400, padding_idx=1)
  )
  (2): LinearDecoder(
    (decoder): Linear(in_features=400, out_features=3464, bias=True)
    (output_dp): RNNDropout()
  )
)], add_time=True, silent=False)

How good is our model? Well, let's try to see what is predicts after a few given words

How to judge the wellness of the lm(language mode) at this step is to be figured out

In [181]:
TEXT = 'I like the phone case as'
N_WORDS = 40
N_SENTENCES = 3
print("\n".join(learn.predict(TEXT, N_WORDS, temperature=0.75) for _ in range(N_SENTENCES)))
I like the phone case as it seems i have a really good screen protector . However , the screen protector is not secure and the phone is much lighter . xxbos i was worried in my phone i buy a bluetooth but now i
I like the phone case as i have the Samsung Galaxy S5 , but this phone is a little smaller . It 's not as difficult to carry in my pocket as many other cases have and it fits well .
I like the phone case as many other cases have , it is very nice and protects my phone perfectly and the color helps me keep up with it better . i wish the case was a bit longer to hold up , but it is
In [185]:
TEXT2 = 'The quality of the phone stand is not very satisfing'
N_WORDS2 = 40
N_SENTENCES2 = 2
In [186]:
print("\n".join(learn.predict(TEXT2, N_WORDS2, temperature=0.20) for _ in range(N_SENTENCES2)))
The quality of the phone stand is not very satisfing but it works well . The price is also very low , but the phone is fine and fit just right . i would recommend this product . xxbos This is a very nice case . It
The quality of the phone stand is not very satisfing but it works well . The price is very low and the quality is very good . xxbos This is a great case for the price . It 's not as grippy as some other cases but

We have to save the model but also it's encoder, the part that's responsible for creating and updating the hidden state. For the next part, we don't care about the part that tries to guess the next word.

In [36]:
learn.save_encoder('fine_tuned_enc_no3')

Classifier

Now we'll create a new data object that only grabs the labelled data and keeps those labels. Again, this line takes a bit of time

In [37]:
df2.to_csv('bi3excluded.csv', sep = ',')
In [38]:
#defaults.cpus=1
path = ''
data_clas = (TextList.from_csv(path, 'bi3excluded.csv', cols = 'reviewText', 
                               vocab=data_lm.vocab)
             .split_by_rand_pct(0.3)
             .label_from_df(cols='overall')
             .databunch(bs=bs))

             #.databunch(bs=bs, num_workers=0,))

defaults.cpus = 1, to avoid issue: BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.

num_workers = 0, to avoid issue: RuntimeError: DataLoader worker is killed by signal

In [39]:
data_clas.save('data_clas_export_no3.pkl')
In [12]:
data_clas = load_data(path, 'data_clas_export_no3.pkl')
In [13]:
data_clas.show_batch()
text target
xxbos i xxup have xxup not xxup used xxup this xxup yet xxup but xxup by xxup the xxup looks i xxup believe xxup its xxup going xxup to xxup be xxup wonderful . i xxup went xxup ahead xxup and xxup purchased xxup another xxup set xxup from a xxup xxunk xxup here xxup in xxup the xxup xxunk xxup and xxup received xxup in 4 xxup days xxup Pos
xxbos xxmaj sadly xxmaj had xxmaj to xxmaj return xxmaj this xxmaj case . xxmaj it 's a xxmaj sturdy xxmaj case & i xxmaj ca n't xxmaj xxunk xxmaj that xxmaj point . xxmaj but xxmaj why xxmaj hide a $ xxunk + xxmaj sexy & xxmaj thin xxmaj phone xxmaj in a xxmaj bulky xxmaj plastic xxmaj case ? xxmaj it xxmaj was xxmaj also a xxmaj bit Neg
xxbos xxup oh xxup my xxup god xxup this xxup is xxup the xxup best xxup ever xxup iphone xxup case xxup xxunk xxup ever xxup bought ! xxmaj seriously , why is it so hard to find a good one ? xxmaj and when you do find one that 's great , it is n't available for your new phone ? xxmaj such was the case with a xxmaj Pos
xxbos xxup pros : \n - xxmaj super durable . xxmaj very good quality materials throughout . \n - xxmaj it locks with two strong xxunk which can then be secure with small xxunk via the 2 holes set near each hinge . \n - xxmaj looks so darn tough . \n - 1 / 4 " foam padding throughout \n - xxmaj waterproof via Pos
xxbos i xxup only xxup rated a 4 xxup star xxup at xxup the xxup moment xxup because i xxup xxunk xxup used xxup them xxup yet xxup and xxup not xxup sure xxup when i xxup will , xxup at xxup the xxup moment i xxup have a xxup armor xxup suit xxup on xxup the xxup screen xxup and xxup by xxup the xxup looks xxup of xxup Pos
In [14]:
learn_clas = text_classifier_learner(data_clas, arch = AWD_LSTM, drop_mult=0.3) # pretrained = True calls for arch=AWD-LSTM 
#drop_mult by default 1: 1 will cause underfitting. It's related to regularization, 
# regularization might cause underfitting. 
In [ ]:
learn_clas.load_encoder('fine_tuned_enc_no3')
In [202]:
learn.freeze()
In [203]:
learn_clas.lr_find() 
0.00% [0/1 00:00<00:00]
epoch train_loss valid_loss accuracy time

74.60% [94/126 01:45<00:35 1.5392]
LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.
In [204]:
learn_clas.recorder.plot(suggestion = True, figsize = (9,9))
Min numerical gradient: 1.32E+00
Min loss divided by 10: 3.02E-02
In [205]:
learn_clas.fit_one_cycle(1, 3.02e-2, moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.315400 0.262931 0.887222 03:08
In [206]:
learn_clas.save('first_no3')
In [207]:
learn_clas.load('first_no3')
Out[207]:
RNNLearner(data=TextClasDataBunch;

Train: LabelList (8091 items)
x: TextList
xxbos xxmaj this is xxup not what you get . xxmaj this case has a sticker with faded coloring on the back or a cheap plastic cover . xxmaj this was not even worth returning . i will not be purchasing a case like this or from this company again .,xxbos xxmaj xxunk says 3 xxrep 4 0 mah 
  xxmaj xxunk reads xxunk mah 
  xxmaj features reads xxunk mah 
  xxmaj makes you wonder xxunk,xxbos xxmaj fit the phone nicely , but the first time i dropped it the glass shattered .,xxbos i ordered 2 of these . i bent the clip on mine the 2nd day i owned it , and i use it on a belt . xxmaj my wife uses xxunk to clip on the edge of her pocket and the clip was n't strong enough to hold . xxmaj neither case would hold a xxmaj samsung xxup s3 with a cover on it , and i 'm talking only a xxunk cover , not one of the xxunk xxmaj xxunk - xxmaj spec ones . xxmaj if you 're using a smaller smartphone , or do n't mind removing the protective cover , it would be an xxup ok case , but even then it would have the crappy clips .,xxbos xxmaj cheap material
y: CategoryList
Neg,Neg,Neg,Neg,Neg
Path: .;

Valid: LabelList (3467 items)
x: TextList
xxbos love the phone works good internet is fast its very pretty its made well xxunk quickly its a good phone for the money,xxbos love it,xxbos fits like a glove ..,xxbos this is a xxunk quality product , it is made of top xxunk leather , very soft and xxunk , great xxunk stitching , it has two loops to put your belt through , also hook to slip over belt , nice low price xxrep 5 !,xxbos xxmaj this is just awesome ! xxmaj xxunk all the tablets and phones and charges all of them at the same time . xxmaj charges quickly too ! i just ca nt say enough about it so far ... xxmaj buy one you will love it ! ! !
y: CategoryList
Pos,Pos,Pos,Pos,Pos
Path: .;

Test: None, model=SequentialRNN(
  (0): MultiBatchEncoder(
    (module): AWD_LSTM(
      (encoder): Embedding(3464, 400, padding_idx=1)
      (encoder_dp): EmbeddingDropout(
        (emb): Embedding(3464, 400, padding_idx=1)
      )
      (rnns): ModuleList(
        (0): WeightDropout(
          (module): LSTM(400, 1152, batch_first=True)
        )
        (1): WeightDropout(
          (module): LSTM(1152, 1152, batch_first=True)
        )
        (2): WeightDropout(
          (module): LSTM(1152, 400, batch_first=True)
        )
      )
      (input_dp): RNNDropout()
      (hidden_dps): ModuleList(
        (0): RNNDropout()
        (1): RNNDropout()
        (2): RNNDropout()
      )
    )
  )
  (1): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
), opt_func=functools.partial(<class 'torch.optim.adam.Adam'>, betas=(0.9, 0.99)), loss_func=FlattenedLoss of CrossEntropyLoss(), metrics=[<function accuracy at 0x1a1f0c0950>], true_wd=True, bn_wd=True, wd=0.01, train_bn=True, path=PosixPath('.'), model_dir='models', callback_fns=[functools.partial(<class 'fastai.basic_train.Recorder'>, add_time=True, silent=False)], callbacks=[RNNTrainer
learn: ...
alpha: 2.0
beta: 1.0], layer_groups=[Sequential(
  (0): Embedding(3464, 400, padding_idx=1)
  (1): EmbeddingDropout(
    (emb): Embedding(3464, 400, padding_idx=1)
  )
), Sequential(
  (0): WeightDropout(
    (module): LSTM(400, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 400, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
)], add_time=True, silent=False)
In [208]:
learn_clas.freeze_to(-2)
learn_clas.fit_one_cycle(1, slice(2.51e-2/(2.6**4),2.51e-2), moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.266890 0.219145 0.909720 03:31
In [209]:
learn_clas.save('second_no3')
In [210]:
learn_clas.load('second_no3')
Out[210]:
RNNLearner(data=TextClasDataBunch;

Train: LabelList (8091 items)
x: TextList
xxbos xxmaj this is xxup not what you get . xxmaj this case has a sticker with faded coloring on the back or a cheap plastic cover . xxmaj this was not even worth returning . i will not be purchasing a case like this or from this company again .,xxbos xxmaj xxunk says 3 xxrep 4 0 mah 
  xxmaj xxunk reads xxunk mah 
  xxmaj features reads xxunk mah 
  xxmaj makes you wonder xxunk,xxbos xxmaj fit the phone nicely , but the first time i dropped it the glass shattered .,xxbos i ordered 2 of these . i bent the clip on mine the 2nd day i owned it , and i use it on a belt . xxmaj my wife uses xxunk to clip on the edge of her pocket and the clip was n't strong enough to hold . xxmaj neither case would hold a xxmaj samsung xxup s3 with a cover on it , and i 'm talking only a xxunk cover , not one of the xxunk xxmaj xxunk - xxmaj spec ones . xxmaj if you 're using a smaller smartphone , or do n't mind removing the protective cover , it would be an xxup ok case , but even then it would have the crappy clips .,xxbos xxmaj cheap material
y: CategoryList
Neg,Neg,Neg,Neg,Neg
Path: .;

Valid: LabelList (3467 items)
x: TextList
xxbos love the phone works good internet is fast its very pretty its made well xxunk quickly its a good phone for the money,xxbos love it,xxbos fits like a glove ..,xxbos this is a xxunk quality product , it is made of top xxunk leather , very soft and xxunk , great xxunk stitching , it has two loops to put your belt through , also hook to slip over belt , nice low price xxrep 5 !,xxbos xxmaj this is just awesome ! xxmaj xxunk all the tablets and phones and charges all of them at the same time . xxmaj charges quickly too ! i just ca nt say enough about it so far ... xxmaj buy one you will love it ! ! !
y: CategoryList
Pos,Pos,Pos,Pos,Pos
Path: .;

Test: None, model=SequentialRNN(
  (0): MultiBatchEncoder(
    (module): AWD_LSTM(
      (encoder): Embedding(3464, 400, padding_idx=1)
      (encoder_dp): EmbeddingDropout(
        (emb): Embedding(3464, 400, padding_idx=1)
      )
      (rnns): ModuleList(
        (0): WeightDropout(
          (module): LSTM(400, 1152, batch_first=True)
        )
        (1): WeightDropout(
          (module): LSTM(1152, 1152, batch_first=True)
        )
        (2): WeightDropout(
          (module): LSTM(1152, 400, batch_first=True)
        )
      )
      (input_dp): RNNDropout()
      (hidden_dps): ModuleList(
        (0): RNNDropout()
        (1): RNNDropout()
        (2): RNNDropout()
      )
    )
  )
  (1): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
), opt_func=functools.partial(<class 'torch.optim.adam.Adam'>, betas=(0.9, 0.99)), loss_func=FlattenedLoss of CrossEntropyLoss(), metrics=[<function accuracy at 0x1a1f0c0950>], true_wd=True, bn_wd=True, wd=0.01, train_bn=True, path=PosixPath('.'), model_dir='models', callback_fns=[functools.partial(<class 'fastai.basic_train.Recorder'>, add_time=True, silent=False)], callbacks=[RNNTrainer
learn: ...
alpha: 2.0
beta: 1.0], layer_groups=[Sequential(
  (0): Embedding(3464, 400, padding_idx=1)
  (1): EmbeddingDropout(
    (emb): Embedding(3464, 400, padding_idx=1)
  )
), Sequential(
  (0): WeightDropout(
    (module): LSTM(400, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 400, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
)], add_time=True, silent=False)
In [211]:
learn_clas.freeze_to(-3)
learn_clas.fit_one_cycle(1, slice(2.51e-3/(2.6**4), 5e-3), moms =(0.8, 0.7))
epoch train_loss valid_loss accuracy time
0 0.168846 0.197326 0.916643 06:21
In [212]:
learn_clas.save('third_no3')
In [213]:
learn_clas.load('third_no3')
Out[213]:
RNNLearner(data=TextClasDataBunch;

Train: LabelList (8091 items)
x: TextList
xxbos xxmaj this is xxup not what you get . xxmaj this case has a sticker with faded coloring on the back or a cheap plastic cover . xxmaj this was not even worth returning . i will not be purchasing a case like this or from this company again .,xxbos xxmaj xxunk says 3 xxrep 4 0 mah 
  xxmaj xxunk reads xxunk mah 
  xxmaj features reads xxunk mah 
  xxmaj makes you wonder xxunk,xxbos xxmaj fit the phone nicely , but the first time i dropped it the glass shattered .,xxbos i ordered 2 of these . i bent the clip on mine the 2nd day i owned it , and i use it on a belt . xxmaj my wife uses xxunk to clip on the edge of her pocket and the clip was n't strong enough to hold . xxmaj neither case would hold a xxmaj samsung xxup s3 with a cover on it , and i 'm talking only a xxunk cover , not one of the xxunk xxmaj xxunk - xxmaj spec ones . xxmaj if you 're using a smaller smartphone , or do n't mind removing the protective cover , it would be an xxup ok case , but even then it would have the crappy clips .,xxbos xxmaj cheap material
y: CategoryList
Neg,Neg,Neg,Neg,Neg
Path: .;

Valid: LabelList (3467 items)
x: TextList
xxbos love the phone works good internet is fast its very pretty its made well xxunk quickly its a good phone for the money,xxbos love it,xxbos fits like a glove ..,xxbos this is a xxunk quality product , it is made of top xxunk leather , very soft and xxunk , great xxunk stitching , it has two loops to put your belt through , also hook to slip over belt , nice low price xxrep 5 !,xxbos xxmaj this is just awesome ! xxmaj xxunk all the tablets and phones and charges all of them at the same time . xxmaj charges quickly too ! i just ca nt say enough about it so far ... xxmaj buy one you will love it ! ! !
y: CategoryList
Pos,Pos,Pos,Pos,Pos
Path: .;

Test: None, model=SequentialRNN(
  (0): MultiBatchEncoder(
    (module): AWD_LSTM(
      (encoder): Embedding(3464, 400, padding_idx=1)
      (encoder_dp): EmbeddingDropout(
        (emb): Embedding(3464, 400, padding_idx=1)
      )
      (rnns): ModuleList(
        (0): WeightDropout(
          (module): LSTM(400, 1152, batch_first=True)
        )
        (1): WeightDropout(
          (module): LSTM(1152, 1152, batch_first=True)
        )
        (2): WeightDropout(
          (module): LSTM(1152, 400, batch_first=True)
        )
      )
      (input_dp): RNNDropout()
      (hidden_dps): ModuleList(
        (0): RNNDropout()
        (1): RNNDropout()
        (2): RNNDropout()
      )
    )
  )
  (1): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
), opt_func=functools.partial(<class 'torch.optim.adam.Adam'>, betas=(0.9, 0.99)), loss_func=FlattenedLoss of CrossEntropyLoss(), metrics=[<function accuracy at 0x1a1f0c0950>], true_wd=True, bn_wd=True, wd=0.01, train_bn=True, path=PosixPath('.'), model_dir='models', callback_fns=[functools.partial(<class 'fastai.basic_train.Recorder'>, add_time=True, silent=False)], callbacks=[RNNTrainer
learn: ...
alpha: 2.0
beta: 1.0], layer_groups=[Sequential(
  (0): Embedding(3464, 400, padding_idx=1)
  (1): EmbeddingDropout(
    (emb): Embedding(3464, 400, padding_idx=1)
  )
), Sequential(
  (0): WeightDropout(
    (module): LSTM(400, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 400, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
)], add_time=True, silent=False)
In [214]:
learn_clas.unfreeze()
learn_clas.fit_one_cycle(2, slice(2.51e-3/(2.6**4),5e-3), moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.130778 0.204868 0.923853 09:42
1 0.086576 0.224664 0.924719 09:03
In [230]:
learn_clas.fit_one_cycle(2, slice(1e-3/(2.6**4),1e-3), moms=(0.8,0.7))
epoch train_loss valid_loss accuracy time
0 0.058870 0.238228 0.921546 07:57
1 0.055476 0.249888 0.921546 10:13
In [215]:
learn_clas.save('final_no3')
In [15]:
learn_clas.load('final_no3')
Out[15]:
RNNLearner(data=TextClasDataBunch;

Train: LabelList (8091 items)
x: TextList
xxbos xxmaj this is xxup not what you get . xxmaj this case has a sticker with faded coloring on the back or a cheap plastic cover . xxmaj this was not even worth returning . i will not be purchasing a case like this or from this company again .,xxbos xxmaj xxunk says 3 xxrep 4 0 mah 
  xxmaj xxunk reads xxunk mah 
  xxmaj features reads xxunk mah 
  xxmaj makes you wonder xxunk,xxbos xxmaj fit the phone nicely , but the first time i dropped it the glass shattered .,xxbos i ordered 2 of these . i bent the clip on mine the 2nd day i owned it , and i use it on a belt . xxmaj my wife uses xxunk to clip on the edge of her pocket and the clip was n't strong enough to hold . xxmaj neither case would hold a xxmaj samsung xxup s3 with a cover on it , and i 'm talking only a xxunk cover , not one of the xxunk xxmaj xxunk - xxmaj spec ones . xxmaj if you 're using a smaller smartphone , or do n't mind removing the protective cover , it would be an xxup ok case , but even then it would have the crappy clips .,xxbos xxmaj cheap material
y: CategoryList
Neg,Neg,Neg,Neg,Neg
Path: .;

Valid: LabelList (3467 items)
x: TextList
xxbos love the phone works good internet is fast its very pretty its made well xxunk quickly its a good phone for the money,xxbos love it,xxbos fits like a glove ..,xxbos this is a xxunk quality product , it is made of top xxunk leather , very soft and xxunk , great xxunk stitching , it has two loops to put your belt through , also hook to slip over belt , nice low price xxrep 5 !,xxbos xxmaj this is just awesome ! xxmaj xxunk all the tablets and phones and charges all of them at the same time . xxmaj charges quickly too ! i just ca nt say enough about it so far ... xxmaj buy one you will love it ! ! !
y: CategoryList
Pos,Pos,Pos,Pos,Pos
Path: .;

Test: None, model=SequentialRNN(
  (0): MultiBatchEncoder(
    (module): AWD_LSTM(
      (encoder): Embedding(3464, 400, padding_idx=1)
      (encoder_dp): EmbeddingDropout(
        (emb): Embedding(3464, 400, padding_idx=1)
      )
      (rnns): ModuleList(
        (0): WeightDropout(
          (module): LSTM(400, 1152, batch_first=True)
        )
        (1): WeightDropout(
          (module): LSTM(1152, 1152, batch_first=True)
        )
        (2): WeightDropout(
          (module): LSTM(1152, 400, batch_first=True)
        )
      )
      (input_dp): RNNDropout()
      (hidden_dps): ModuleList(
        (0): RNNDropout()
        (1): RNNDropout()
        (2): RNNDropout()
      )
    )
  )
  (1): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
), opt_func=functools.partial(<class 'torch.optim.adam.Adam'>, betas=(0.9, 0.99)), loss_func=FlattenedLoss of CrossEntropyLoss(), metrics=[<function accuracy at 0x1a26ed4290>], true_wd=True, bn_wd=True, wd=0.01, train_bn=True, path=PosixPath('.'), model_dir='models', callback_fns=[functools.partial(<class 'fastai.basic_train.Recorder'>, add_time=True, silent=False)], callbacks=[RNNTrainer
learn: ...
alpha: 2.0
beta: 1.0], layer_groups=[Sequential(
  (0): Embedding(3464, 400, padding_idx=1)
  (1): EmbeddingDropout(
    (emb): Embedding(3464, 400, padding_idx=1)
  )
), Sequential(
  (0): WeightDropout(
    (module): LSTM(400, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 1152, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): WeightDropout(
    (module): LSTM(1152, 400, batch_first=True)
  )
  (1): RNNDropout()
), Sequential(
  (0): PoolingLinearClassifier(
    (layers): Sequential(
      (0): BatchNorm1d(1200, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (1): Dropout(p=0.12, inplace=False)
      (2): Linear(in_features=1200, out_features=50, bias=True)
      (3): ReLU(inplace=True)
      (4): BatchNorm1d(50, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): Dropout(p=0.1, inplace=False)
      (6): Linear(in_features=50, out_features=2, bias=True)
    )
  )
)], add_time=True, silent=False)
In [217]:
learn_clas.show_results()
text target prediction
xxbos i xxup super xxup love xxup this xxup case xxup my xxup xxunk xxup saw xxup this xxup when xxup he xxup came xxup home xxup from xxup work xxup on xxup my xxup phone xxup and xxup wanted xxup to xxup see xxup what xxup it xxup looked xxup like xxup on xxup his xxup phone xxup and xxup well xxup let xxup 's xxup just xxup say Pos Pos
xxbos xxup this xxup phone xxup has xxup to xxup be xxup charged xxup every xxup half xxup an xxup hour . xxup for a 3 g xxup phone xxup this xxup is a xxup terrible xxup terrible xxup product xxup and xxup even xxup though xxup you xxup can xxup download xxup apps xxup xxunk xxup the xxup sense xxup when xxup the xxup battery xxup runs xxup out Neg Neg
xxbos xxmaj after using for more than a week i can say this is one of the good xxunk i have used for now . xxmaj here below i have mentioned my xxunk in the form of xxup pros and xxup cons . xxmaj hope this helps you figure if this product is best for your . \n xxup pros : \n 1 . xxmaj good grip in Pos Pos
xxbos xxmaj good purchase . xxmaj xxunk 14 , 16 . xxmaj update ; really happy with it . xxmaj use daily , charge during the day using my xxmaj anker solar panel . xxmaj charges my phones , radios then in the xxunk it provides power for the xxup xxunk led light . xxmaj now folks , i can not turn it off . xxmaj problem with the switch Pos Pos
xxbos xxmaj overall : \n i was looking for a durable case for my almost 3 year old xxup htc xxmaj inspire ( do n't ask me why i got a case after so long xxup xxunk ) , something that can xxunk occasional drops , and i found this . xxmaj the product turned out to be true to its description , and i am happy with it Pos Pos
In [16]:
preds, target = learn_clas.get_preds()
In [17]:
interp = ClassificationInterpretation.from_learner(learn_clas)
In [18]:
interp.plot_confusion_matrix()
In [19]:
#accuracy:
acc = (2628+578)/(2628+578+158+103)
acc
Out[19]:
0.9247187770406692
In [20]:
# sensitivity: true positive detect as true tp/(tp+fn)
sen= (2628/(2628+103))
sen
Out[20]:
0.9622848773343098
In [21]:
#specificity: tn/(tn+fp)
spec = (578/(578+158))
spec
Out[21]:
0.7853260869565217
In [22]:
pre = (2628/(2628+158))
pre
Out[22]:
0.9432878679109835
In [23]:
f1 = 2*(pre*sen)/(pre+sen)
f1
Out[23]:
0.9526916802610115
In [24]:
y_test = list(target.numpy())
y_pred = preds.numpy()[:,1]
In [25]:
import matplotlib.pyplot as plt 
from sklearn.metrics import roc_curve, auc
In [26]:
fpr, tpr, thresholds = roc_curve(y_test, y_pred)
#fpr: false positive rate = FP/N = (FP/FP+TN) fall-out/false alarm ratio:  rate of negative incorrectly detected as positive 
#tpr: true positive rate = TP/P= (TP/TP+FN) = sensitivity, rate of a true positive detected as true
In [27]:
auc_score = auc(fpr, tpr)
In [28]:
plt.plot([0,1], [0, 1], 'k--')
plt.plot(fpr, tpr, label = 'Area = {:.3f}'.format(auc_score))
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.title('ROC curve')
plt.legend(loc='best')
plt.show()
plt.savefig('binaryno3.png')
<Figure size 432x288 with 0 Axes>
In [29]:
import scikitplot as skplt
y_preds_arr = preds.numpy()
skplt.metrics.plot_cumulative_gain(y_test, y_preds_arr)
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a2f176d90>
In [30]:
skplt.metrics.plot_lift_curve(y_test, y_preds_arr)
Out[30]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a28cafc10>
In [31]:
def biggernum(arr):
    if arr[0] > arr[1]:
        return arr[0]
    else: 
        return arr[1]
In [32]:
def prediction(str): 
    pred = learn_clas.predict(str)
    print('The review belongs to class: ', pred[0], ',',  'with a scale of ', '{:.2f} '.format(biggernum(pred[2].numpy()) * 100), 'out of 100.') 
In [ ]:
msg = "This table is complete garbage. The materials are substandard and the overall quality is below what a collage freshman would even expect."
prediction(msg)
In [29]:
msg = "Sturdy enough to serve as a coffee table or a tv stand! I bought this for my friend who moved into a new apartment so that he could have a nice coffee table but since his tv was sitting on the floor he decided to use it as a tv stand instead and it looked great. I MIGHT buy him another one to use for the intended purpose."
prediction(msg)
The review belongs to class:  Pos , with a scale of  100.00  out of 100.
In [63]:
# this is a 3 star rating product review from Amazon, for a furniture. 
learn_clas.predict("Doesn't assemble too well. Parts and studs stick out. The mica breaks or chips easily. Be careful when assembling, the holes have not been drilled properly and you might have some issues.")
Out[63]:
(Category Neg, tensor(0), tensor([0.9811, 0.0189]))
In [65]:
learn_clas.predict( "Sturdy enough to serve as a coffee table or a tv stand! I bought this for my friend who moved into a new apartment so that he could have a nice coffee table but since his tv was sitting on the floor he decided to use it as a tv stand instead and it looked great. I MIGHT buy him another one to use for the intended purpose.")
Out[65]:
(Category Pos, tensor(1), tensor([2.1417e-05, 9.9998e-01]))
In [33]:
def get_score2(string):
    score =[]
    pred=learn_clas.predict(string)
    score.append(round(pred[2].numpy()[1]*100,3))
    score.append(round(pred[2].numpy()[0]*100,3))
    return score
In [34]:
import plotly.graph_objects as go
import matplotlib.pyplot as plt
In [35]:
def plot_go(string):
    colors = ['lightgreen', 'white']
    fig = go.Figure(data=[go.Pie(labels = ['Positive', ' '], 
                            values = get_score2(string))])
    fig.update_traces(
        hoverinfo = 'label+percent', textinfo = 'value' , textfont_size =15,
                      textposition = 'inside',
                     marker=dict(colors=colors, line=dict(color = '#001000', width =1)))
    fig.update_layout(title = {"text": 'Your Business Performance is {:.2f} out of 100'.format(get_score2(string)[0]),
                              'y': 0.9, 'x': 0.5, 
                              'xanchor': 'center', 
                              'yanchor': 'top'})
                     #paper_bgcolor ='lightyellow')
    
    fig.show()
In [36]:
def get_score(string):
    pred = learn_clas.predict(string)
    scores = [round(biggernum(pred[2].numpy()*100), 2), round(100- biggernum(pred[2].numpy()*100),2)] 
    return scores

def cat(string):
    pred = learn_clas.predict(string)
    category = pred[0].obj
    if category=='Pos':
        pred_cat = ['Positive', 'Negative'] 
    else:
        pred_cat = ['Negative', 'Positive'] 
    return pred_cat

def col(string):
    if cat(string) ==['Positive', 'Negative']: 
        colors = ['green', 'red']
    else: 
        colors = ['red','green']
    return colors

def title(string):
    if cat(string) ==['Positive', 'Negative']: 
        title = 'Well Done!'
    else: 
        title = 'Ummm... Attention!'
    return title

def label_result(string):
    labels = []
    for i in range(2):
        labels.append(cat(string)[i])
        labels.append(get_score(string)[i])
    labels= np.reshape(labels, (2,2)).tolist()
    return labels

def title_color(string):
    if cat(string) ==['Positive', 'Negative']: 
        color = 'green'
    else: 
        color = 'red'
    return color
In [37]:
def plot_result(string): 
    plt.figure(figsize=(8,6))
    plt.pie(get_score(string), labels = label_result(string), colors = col(string))
    plt.title(title(string), color = title_color(string), size = 30)
    my_circle=plt.Circle((0,0), 0.5, color = 'white')
    p = plt.gcf()
    p.gca().add_artist(my_circle)
    plt.show()
In [62]:
def plot_resultgo(string):
    fig = go.Figure(data=[go.Pie(labels = label_result(string), values = get_score(string), hole=0.5)])
    fig.update_traces(textinfo='label', textfont_size=15,
                  marker=dict(colors=col(string),)) 
    fig.update_layout(title_text = title(string), titlefont_size =30,titlefont_color = title_color(string),
                      showlegend=True)
    #fig.show()
In [38]:
def plot_resultgo2(string):
    fig = go.Figure(data=[go.Pie(labels = label_result(string), values = get_score(string), hole=0.5)])
    fig.update_traces(hoverinfo='label', textinfo='label', textfont_size=15,
                  marker=dict(colors=col(string),)) 
    fig.update_layout(title_text = title(string), titlefont_size =30,titlefont_color = title_color(string),
                      showlegend=True)
    fig.show()
In [126]:
plot_result('not good at all')
In [127]:
plot_result('I love this phone case')
In [128]:
plot_result("Cellulartech Says warranty is in Latin America but not here in USA , so after hours of research , calls etc. trying I get a rep at the so called Samsung-Latin which said their policy is 'YOU GET NO WARRANTY'")
In [130]:
plot_result("It is too short. I thought it would be much longer.")
In [131]:
plot_result("I am at fault because I did not look at the measurement for the length. It is the same size as my regular rolling pin. I would have returned, but I missed the deadline. I will use for my Thanksgiving baking, so I do not know the quality of the item or if I will prefer it to my other rolling pin.")
In [39]:
plot_go("I lost my Anker powerbank recently and had to get a new one, but I didn’t want to buy the same Anker one so I tried this powerbank instead, since the watts are a lot higher than my Anker. Needless to say, it did its job, and lasted maybe longer and charged faster than my Anker! I’m surprised and satisfied with my purchase! One thing that I kinda thought was a downside was that it was pretty heavy, but it isn’t too bad!")
In [40]:
plot_go("This unit only charges my phone (3000 mA) 4.5 times, and it should do at least 8 times. My other power bank (26,800 mA) does charge my phone over 8 times. This should be advertised as a 15,000 mA capacity power bank, and not more.")
In [41]:
plot_go("It seemed like a good charger but I did not use before returning it. I found it to be too heavy to carry with me, so I returned it.")
In [43]:
plot_go("this phone case is cute, but it's not that sturdy...")
In [42]:
get_score("I ordered a necklace over a week ago and it still has not yet arrived")
# it is actually a complaint, so what's the difference between complaint and negative sentiment?
Out[42]:
[89.71, 10.29]
In [81]:
# same product, 1 star rating review
learn_clas.predict("This table is complete garbage. The materials are substandard and the overall quality is below what a collage freshman would even expect.")
C:\Users\test\Anaconda3\lib\site-packages\fastai\torch_core.py:83: UserWarning: Tensor is int32: upgrading to int64; for better performance use int64 input
  warn('Tensor is int32: upgrading to int64; for better performance use int64 input')
Out[81]:
(Category Neg, tensor(0), tensor([0.9987, 0.0013]))
In [82]:
# 5 star rating for another furniture on Amazon
learn_clas.predict("Sturdy enough to serve as a coffee table or a tv stand! I bought this for my friend who moved into a new apartment so that he could have a nice coffee table but since his tv was sitting on the floor he decided to use it as a tv stand instead and it looked great. I MIGHT buy him another one to use for the intended purpose.")
C:\Users\test\Anaconda3\lib\site-packages\fastai\torch_core.py:83: UserWarning: Tensor is int32: upgrading to int64; for better performance use int64 input
  warn('Tensor is int32: upgrading to int64; for better performance use int64 input')
Out[82]:
(Category Pos, tensor(1), tensor([3.4414e-04, 9.9966e-01]))
In [248]:
plot_go("A little too big for my Pomeranian Jack Russle mix. I wish it was made with one or two more holes in the leather strap. Also I wish there was a “hold down” piece for the remaining leather strap so it doesn’t just hang there uncomfortably. Other than that the quality is good.")
In [249]:
plot_go("It's a very nice looking collar and my dog looks handsome in it, but the leather is worn just about clean through after roughly 6 months of use.")
In [44]:
plot_go("For the price I thought this would be a great quality collar. The leather part is not good.")
In [251]:
plot_go("I have a 80-90 lb lab and this hold up and is really beautiful leather like material !!! We go hiking and in the lake all summer and this hold up wonderfully and is strong and cute !")
In [252]:
plot_go("It's a little more dull brown and not so vibrant as the picture shows, just an observation it still looks great. I'd love for my dog to wear it but it didn't come with any holes punched, it didn't say anywhere that I was suppose to punch them myself...")
In [253]:
plot_go("When I first got this collar I loved it, it was pretty and seemed durable. Seriously after 2 weeks it started peeling and cracking. There is no way that this should have happened after 2 weeks of having it on my pit bull, Pixie. She’s not an overly hyper dog. I had to go out and buy another collar for her. Extremely disappointed.2 people found this helpful")
In [254]:
plot_go("Ordered the tan leather option. Very disappointing. The leather is a different color than what’s pictured, much darker. Doesn’t look at all like what’s shown in the picture.")
In [61]:
plot_go("works great if you like to look at your phone sideways ia a total pain in the ass for a vertical look! can't imagine why anyone would want to view their phone sideways while in the car!")
In [62]:
plot_go("The concept of this phone holder is great but it does not stick to my textured dash. It's not worth the frustration to try and get it to stick. We tried exchanging for the same thing thinking it was defective but the second didn't work either. So we are returning both of them for a refund.")
In [63]:
plot_go("I dislike because if you have it in the Vertical position you cannot plug in to charge your phone, only in horizontal you can charge")
In [64]:
plot_go("Well it would work if when it stands up you could charge it,Other then that it’s fine but i need it to stand and be changed")
In [44]:
(413+1797)/(413+1797+53+48)
Out[44]:
0.9562959757680658
In [45]:
(1797/(1797+53))
Out[45]:
0.9713513513513513
In [46]:
413/(413+48)
Out[46]:
0.89587852494577
In [47]:
(1797/(1797+48))
Out[47]:
0.9739837398373984
In [49]:
2628/(2628+158)
Out[49]:
0.9432878679109835